package com.alibaba.citrus.cr.mn.order.center.facade.function.common;

import com.alibaba.citrus.cr.mn.order.center.common.util.StopWatchUtils;
import com.alibaba.citrus.cr.mn.order.center.facade.function.check.AbstractOrderParamsCheckService;
import com.alibaba.cz.base.tool.log.Log;
import com.epoch.app.mnordercenter.orderbaserequest.OrderAtomUpdateRequest;
import com.epoch.app.mnordercenter.orderbaserequest.OrderAtomUpdateResponse;
import com.epoch.app.mnordercenter.salesorderatom.dto.SapModifyCallbackRequest;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.StopWatch;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * Chen.mu
 * 2023/5/12
 **/
public interface OrderAtomUpdateService {

    String CORE_STOP_WATCH_SEQ = "订单中心原子修改";

    Log log = Log.getLogger(OrderAtomUpdateService.class);

    /**
     * 修改订单
     */
    default OrderAtomUpdateResponse update(OrderAtomUpdateRequest request) {
        //商业的因仓库 货品信息已拼装并校验好，可直接走更新
        //原子商业因可能再待提交状态下 存在更新仓库 货品信息，需要回填数据到request中进行匹配。
        try {
            OrderAtomUpdateResponse response = new OrderAtomUpdateResponse();

            // 根据OrderCategoryCode判断是否为商业接口调用，原子接口调用时为空，才进行入参回填和入参校验
            if (StringUtils.isBlank(request.getOrderCategoryCode())) {
                // 区分明细操作逻辑，新增or修改
                compareAndSpiltDetail(request);

                // 入参校验
                response = paramsInvalidCheck(request);
                if (StringUtils.isNotBlank(response.getErrorCode()) || StringUtils.isNotBlank(response.getMessage())) {
                    // 入参校验没通过，直接返回报错
                    return response;
                }
            }

            // 4.0 数据库事务提交
            submitSaveTransactional(request, response);

            // 5.0 后置处理：SAP创单消息发送+其他业务处理 (目前放置在上层处理，可以考虑事件驱动实现)
            afterSubmitTransactional();

            // 5.5 打印链路耗时日志
//            printExecConsumerTime();

            return response;
        } catch (Exception e) {
            log.error("OrderAtomUpdateService#update error", e);
            throw e;
        }
    }

    default void compareAndSpiltDetail(OrderAtomUpdateRequest request) {
        throw new RuntimeException("此方法未被实现");
    }

    default OrderAtomUpdateResponse paramsInvalidCheck(OrderAtomUpdateRequest request) {
        StopWatchUtils.start(CORE_STOP_WATCH_SEQ, "paramsInvalidCheck");
        if (getCheckService() != null) {
            List<OrderAtomUpdateResponse> responseList = new ArrayList<>();
            getCheckService().paramsInvalidCheck(Lists.newArrayList(request), responseList);
            if (CollectionUtils.isNotEmpty(responseList)) {
                return responseList.get(0);
            }
        } else {
            throw new RuntimeException("paramsInvalidCheck未被实现");
        }
        StopWatchUtils.stop();
        return new OrderAtomUpdateResponse();
    }

    default void submitSaveTransactional(OrderAtomUpdateRequest request, OrderAtomUpdateResponse response) {
        throw new RuntimeException("此方法未被实现");
    }

    default void submitSaveTransactionalNew(OrderAtomUpdateRequest request, OrderAtomUpdateResponse response) {
        throw new RuntimeException("此方法未被实现");
    }

    default void afterSubmitTransactional() {
        // 默认不实现后置处理
    }

    default void printExecConsumerTime() {
        StopWatch currStopWatch = StopWatchUtils.clear(); // 移除ThreadLocal中存储对象
        if (Objects.nonNull(currStopWatch)) {
            log.info("OrderAtomUpdateService#afterSubmitTransactional stopWatch.getTotalTimeSeconds()={}",
                    currStopWatch.getTotalTimeSeconds());
            log.info("OrderAtomUpdateService#afterSubmitTransactional stopWatch.prettyPrint()={}",
                    currStopWatch.prettyPrint());
        }
    }

    /**
     * 指定单据类型
     * 销售订单：normal
     * 退货订单：return
     * 换货订单：exchange
     */
    String getOrderTag();

    AbstractOrderParamsCheckService getCheckService();

    void modifyCallback(SapModifyCallbackRequest sapModifyCallbackRequest);

}
